<template>
  <div class="write-license-container">
	  <div class="write-license">
		<el-form ref="form" :model="writeForm" label-width="70px" label-position="left">
		  <el-form-item label="串 口">
			<el-col :span="7">
			<el-input v-model="writeForm.portName"/>
			</el-col>
			<el-button type="primary" class="change-btn" size="medium" @click="portSelect">选择串口</el-button>
		  </el-form-item>
		   <el-col :span="6">
		 <el-form-item label="波特率">
			<el-select v-model="writeForm.baudRate" size="medium" class="select" :disabled="disabled">
				 <el-option 
				  v-for="item in baudRateList"
				  :key="item.value"
				  :label="item.label"
				  :value="item.value">
				</el-option>
			</el-select>
		  </el-form-item>
		   </el-col>
		   <el-col :span="6">
		  <el-form-item label="校验位">
			<el-select v-model="writeForm.parity" size="medium" class="select" :disabled="disabled">
			 <el-option
			   v-for="item in parityList"
			   :key="item.value"
			   :label="item.label"
			   :value="item.value">
			 </el-option>
			</el-select>
		   </el-form-item>
		   </el-col>
		   <el-col :span="6">
		   <el-form-item label="停止位">
				<el-select v-model="writeForm.stopBits" size="medium" class="select" :disabled="disabled">
				  <el-option
				    v-for="item in stopBitsList"
				    :key="item.value"
				    :label="item.label"
				    :value="item.value">
				  </el-option>
				</el-select>
		    </el-form-item>
			</el-col>
			<el-col :span="6">
			<el-form-item label="数据位">
				<el-select v-model="writeForm.dataBits" size="medium" class="select" :disabled="disabled">
				  <el-option
				    v-for="item in dataBitsList"
				    :key="item.value"
				    :label="item.label"
				    :value="item.value">
				  </el-option>
				</el-select>
			 </el-form-item>
			</el-col>
			<el-button type="primary" :disabled="disabled" @click="serialOpen">打开串口</el-button>
			<el-button type="warning" :disabled="!disabled" @click="serialClose">关闭串口</el-button>
		  </el-form-item>
			<div class="box-wrapper">
				<div class="box">
					<div class="btn-wrapper">
						<el-button type="primary" size="medium" @click="handledData">手动查询</el-button>
						<el-button type="success" size="medium" @click="serialSend">读取数据</el-button>
						<el-button  type="warning" size="medium" @click="recycle" :disabled="writeForm.status==1||writeForm.status===0">重置SN</el-button>
						<!-- <el-button  type="warning" size="medium" @click="recycle">回收License</el-button> -->
					</div>
					<el-form-item label="SN:" label-width="80px">
						<el-input v-model="writeForm.sn" @input="changeInput"/>
					</el-form-item>
					<el-form-item label="License:" label-width="80px">
						<el-input v-model="writeForm.license" />
						<p class="tip" v-if="writeForm.status==1">license已被写入过</p>
					</el-form-item>
					<el-form-item label="转入客户:" label-width="80px">
						<el-select v-model="writeForm.customer" filterable placeholder="请选择" :disabled="writeForm.status==1||writeForm.status===0" style="width: 100%;">
						    <el-option
						      v-for="item in customerList"
						      :key="item.customnumber"
						      :label="item.customname"
						      :value="item.customnumber">
						    </el-option>
						</el-select>
					</el-form-item>
					<!-- <div class="submit">
						<el-button  type="warning" size="medium" @click="recycle">重置SN</el-button>
					</div> -->
				</div>
			</div>
		</el-form>
	</div>
  </div>
</template>

<script>
import { licenseRecordQuerySn, customerList, resetSn} from "@/api/recycle";
export default {
  data() {
    return {
		port: null,
		reader:null,
		keepReading: true,
		disabled:false,
		snReturnVal:'',
		writeForm: {
			portName: '',
			baudRate: '115200',//波特率
			parity:'none',//校验位
			stopBits: '1',//停止位
			dataBits: '8',//数据位
			sn:'',
			license:'',
			customer:'',//客户
			status:0, //1已写入 ；null未写入
		},
		//波特率下拉列表
		baudRateList:[{
			  value: '1200',
			  label: '1200'
			}, {
			  value: '2400',
			  label: '2400'
			}, {
			  value: '4800',
			  label: '4800'
			}, {
			  value: '9600',
			  label: '9600'
			}, {
			  value: '115200',
			  label: '115200'
		}],
		//校验位下拉列表
		parityList:[{
				value: 'none',
				label: 'none'
			}, {
				value: 'odd',
				label: 'odd'
			}, {
				value: 'even',
				label: 'even'
		}],
		//停止位下拉列表
		stopBitsList:[{
				value: '1',
				label: '1'
			}, {
				value: '2',
				label: '2'
		}],
		//数据位下拉列表
		dataBitsList:[{
				value: '8',
				label: '8'
			}, {
				value: '7',
				label: '7'
		}, {
				value: '6',
				label: '6'
		}, {
				value: '5',
				label: '5'
		}],
		customerList: [],
		snList: [],//sn清单
    }
  },
  destroyed(){
  	  //离开当前页面前先关闭串口，避免下次进入时串口被占用
  	  this.serialClose()
  },
  created() {
  	this.getCustomerList()
  },
  methods: {
	//获取所有客户列表  
	getCustomerList(){
		customerList().then(response=>{
			this.customerList = response.rows
		})
	},  
	// 数组类型转化为16进制字符串
	uint8Array(uint8Array) {
	    return Array.prototype.map
	  	.call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
	  	.join('');
	},
	  // 16进制转uint8Array
	fromHexString(hexString){
	  	return new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
	},
	//sn发生更改时清除license输入框内容
	changeInput(){
		this.writeForm.license = ""
		this.writeForm.status = 0;
	},
	  //选择串口
	async portSelect(){
		this.port = await navigator.serial.requestPort();
		/* const ports = await navigator.serial.getPorts();
		console.log(JSON.stringify(ports));
		let name = this.port
		console.log(JSON.stringify(this.port.getInfo())); */
		if (this.port) {
			this.writeForm.portName = JSON.stringify(this.port.getInfo())
		}
	},
	//打开串口
	async serialOpen(){
		let that = this;
		that.keepReading = true;
		if (that.port == null) {
			// alert('打开串口出错');
			that.$message('打开串口出错!')
			return;
		}
		let opt = {
			baudRate: 115200,
			parity: 0,
			dataBits: 8,
			stopBits: 1
		};
		opt.baudRate = parseInt(that.writeForm.baudRate);
		opt.parity = that.writeForm.parity;
		opt.dataBits = parseInt(that.writeForm.dataBits);
		opt.stopBits = parseInt(that.writeForm.stopBits);
		
		// Wait for the serial port to open.
		try{
			await that.port.open(opt);
			that.$message.success('串口已打开!')
		} catch (error) {
			console.log(error);
			// alert("串口已被占用")
			that.$message('串口已被占用!')
			return;
			// TODO: Handle non-fatal read error.
		}
		
		that.disabled = true;
		while (that.port.readable && that.keepReading) {
			that.reader = that.port.readable.getReader();
		
			try {
				while (true) {
					const { value, done } = await that.reader.read();
					
					if (done) {
						// 允许稍后关闭串口.
						that.reader.releaseLock();
						break;
					}
					if (value) {
						//value is a Uint8Array.
						// console.log(value);
						let utf8decoder = new TextDecoder()
						let u8arr = new Uint8Array(value);
						//将Uint8Array字节组转成16进制字符串，并将字母转大写
						let strvalue = that.uint8Array(u8arr).toUpperCase()
						
						// console.log(strvalue);
						// const temp = that.writeForm.sn;
						// that.writeForm.sn = temp + strvalue
						that.snReturnVal += strvalue
						// console.log(that.writeForm.sn);
						/* const temp = $("#receiverText").val();
						$("#receiverText").val(temp + strvalue); */
					}
				}
			} catch (error) {
				console.log(error);
				// TODO: Handle non-fatal read error.
			}finally {
			  // 允许稍后关闭串口。
			  that.reader.releaseLock();
			}
		}
		// await that.port.close();
	},
	//查询license
	handledData(){
		let sn = this.writeForm.sn;
		if (sn.length < 1) {
			this.$message.error('请先填写SN码!');
		} else{
			licenseRecordQuerySn({sn}).then(response => {
				let {uid, writeStatus} = response.data;
				this.writeForm.license = uid;
				this.writeForm.status = writeStatus;
				// this.writeForm.status = 0;
				// this.writeForm.status = 1;
				
			}).catch(err=>{
				//删
				this.writeForm.status = 0;
			});
		}
	},
	//将字符串按每两位倒序返回字符串
	strToReverseStr(str){
		// console.log(str);
		var list=[];
		var ar2 = 0;
		for(let i = 0; i < str.length-1; i+=2){
		list.push((str.substring(i, i + 2)))
		}
		let newCode = list.reverse().join('').toLowerCase()
		// console.log(newCode)
		return newCode
	},
    //读取串口
	async serialSend() {
	  let that = this;
	  if(this.disabled === false){
		  this.$message('请先点击打开串口!');
		  return;
	  }
	  this.writeForm.sn = ""
	  const data = "EFAA800000000080";//读取sn编码
	  const writer = this.port.writable.getWriter();
	  let unitData = this.fromHexString(data)// 16进制转uint8Array
	  await writer.write(unitData);
	  writer.releaseLock();
	  setTimeout(function(){
	  	// console.log(that.snReturnVal);
	  	let code1 = that.snReturnVal.substring(18,26)
	  	code1 = that.strToReverseStr(code1)
	  	let code2 = that.snReturnVal.substring(26,35)
	  	code2 = that.strToReverseStr(code2)
	  	that.writeForm.sn = code1 + code2;
		that.handledData()
	  },100)
    },
	//关闭串口
	async serialClose(){
		this.disabled = false
		let that = this;
		// 清除输入框数据
		this.writeForm.portName = "";
		this.writeForm.sn = "";
		this.writeForm.license = "";
		this.writeForm.customer = "";
		try {
			that.keepReading = false
			await that.reader.cancel();
			await that.port.close();
		} catch (e) {
			console.log("报错："+ e);
			//TODO handle the exception
		}
	},
	//回收License
	recycle(){
		// alert("触发重置\nSN："+this.writeForm.sn+"\n客户："+this.writeForm.customer)
		let params = {
			sn: this.writeForm.sn,
			customer:this.writeForm.customer
		}
		resetSn(params).then(res=>{
			console.log(res);
			this.$message.success(res.msg)
		})
	}
  }
}
</script>

<style lang="scss" scoped>
.write-license-container{
  background-color: #fff;
  border-radius: 8px;
  min-height: 500px;
  .write-license{
	  padding: 30px 30px;
	  .change-btn{
		  margin-left: 10px;
	  }
	  .select{
		  width: 150px;
	  }
	  .box-wrapper{
		  display: flex;
		  justify-content: flex-start;
		  padding: 10px 0;
		  margin-top: 20px;
		  .box{
			  border: 1px dashed #ccc;
			  border-radius: 8px;
			  padding: 20px 30px;
			  width: 600px;
			  &:first-child{
				  margin-right: 30px;
			  }
			  .btn-wrapper{
				  padding: 20px 0;
				  text-align: right;
			  }
			  .submit{
				  text-align: center;
			  }
			  .tip{
				  color: red;
				  margin: 0;
				  padding: 0;
				  height: 5px;
				  font-size: 12px;
				  line-height: 20px;
			  }
		  }
	  }
  }
}
</style>

